-- UILictorChoose
-- Create by chendh
-- 扈从选择界面

require "game/ui/form/hero/HeroUtil"

-- UILictorChoose继承自Layer
UILictorChoose = class("UILictorChoose", function()
    return cc.Layer:create();
end);

function UILictorChoose.create(classId, itemId, lictorPets)
    return UILictorChoose.new(classId, itemId, lictorPets);
end

-- 扈从格最大行数
local MIN_GRID_COLUMN = 4;
local MAX_GRID_ROW    = 6;
local ITEM_NAME       = "item";

-- 构造函数
function UILictorChoose:ctor(classId, itemId, lictorPets)
    -- 初始化
    self:setName("UILictorChoose");
    local node = cc.CSLoader:createNode("layout/lictor/LictorChoose.csb");
    self:addChild(node);
    self.node = node;

    local CT = node:getChildByName("CT");
    self.CT = CT;
    local scroll_view = findChildByName(self.node, "CT/bg_1/scroll_view");
    self.scrollView = scroll_view;

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    self.itemId = itemId;
    self.rankRequest = itemId;
    self.classId = classId;
    self.selectIndex = 1;
    self.lictorPets = lictorPets;

    self.campId = CampM.getPetCamp(classId);
    self.campPets = CampM.getCampPets(classId);
    self.campName = CampM.query(self.campId, "name");

    -- 注册点击事件
    self:registerTouchEvent();

    self:initData();

    -- 初始化扈从格子
    self:initLictorGrids(self.node);

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            cclog("UILictorChoose 界面析构清理");
            EventMgr.removeAll("UILictorChoose");

            local UIEnterDungeon = UIMgr.getCurrentScene():getFormByName("UIEnterDungeon");
            if UIEnterDungeon then
                UIEnterDungeon:setVisible(true);
            end
        elseif ev == "enter" then
            local UIEnterDungeon = UIMgr.getCurrentScene():getFormByName("UIEnterDungeon");
            if UIEnterDungeon then
                UIEnterDungeon:setVisible(false);
            end
        end
    end);
end

-- 重绘
function UILictorChoose:redraw()
    -- 绘制标题
    local titleLabel = findChildByName(self.CT, "title/title_label");
    titleLabel:setString(string.format(getLocStr("lictor_title"), covertNumToRoman(self.itemId - 2)));
    TextStyleM.setTitleStyle(titleLabel);

    -- 绘制副标题
    -- 获取冈布奥的阵营
    local titleExplainLabel = findChildByName(self.CT, "title/title_explain");
    titleExplainLabel:setString(string.format(getLocStr("lictor_title_explain"), self.campName));
    TextStyleM.setSubheadStyle(titleExplainLabel);

    -- 绘制页面
    local itemCount = #self.data;
    local index = 0;

    if not self.data or itemCount == 0 then
        cclog("收集扈从信息失败。");
        self:clearAllGrid();
        return;
    end

    -- 找到第一个可派遣
    for i = 1, itemCount do
        local data = self.data[i];
        if data then
            -- 有数据
            if PetM.getMyPet(data.classId) then
                if self:canDispatch(data.classId) and not self:islistor(data.classId) then
                    self.selectIndex = i;
                    break;
                end
            end
        end
    end

    for index = 1, itemCount do
        -- 获取扈从格
        local child = self.scrollView:getChildByName(ITEM_NAME .. index);
        if child == nil then
            break;
        end

        -- 设置选中效果
        local focusBg = child:getChildByName("focus");
        if self.selectIndex == index then
            focusBg:setVisible(true);
        else
            focusBg:setVisible(false);
        end

        -- 扈从格文本
        local str = "";
        -- 扈从格背景
        local bgImg = child:getChildByName("bg");
        local bgImgGray = child:getChildByName("gray_bg");
        -- 扈从icon
        local iconImage = child:getChildByName("icon");
        -- 扈从格星级
        local starImage = child:getChildByName("rank");
        -- "已链接"的tip
        local tipImage = child:getChildByName("tip");

           -- 系别图标
        local departImg = child:getChildByName("depart_img");

        -- 默认全部隐藏
        bgImg:setVisible(false);
        bgImgGray:setVisible(false);
        iconImage:setVisible(false);
        starImage:setVisible(false);
        tipImage:setVisible(false);
        departImg:setVisible(false);

        local data = self.data[index];
        if data then
            -- 有数据

            -- 设置宠物头像
            local  pet = PetM.getMyPet(data.classId);
            iconImage:setVisible(true);

            if pet then
                -- 玩家已获得该宠物
                local iconIndex = pet:getIcon();
                iconImage:loadTexture(getHeroIconPath(iconIndex));

                -- 系别图标
                departImg:loadTexture(getCareerDepartmentIconPath(data.depart));
                departImg:setVisible(true);

                if self:canDispatch(data.classId) then
                    -- 可以派遣
                    -- 正常显示头像、背景、星级
                    iconImage:setOpacity(255);
                    bgImg:setVisible(true);

                    -- 设置星阶
                    -- 星级控件
                    starImage:setVisible(true);
                    if data then
                        local starPath = "images/ui/symbol/star_little.png";

                        -- 如果冈布奥已觉醒，使用橙色的星星
                        if AwakeM.isCarved(data.classId) then
                            starPath = "images/ui/symbol/star_little3.png";
                        end
                        local tStar = createStarLayer(data.rank, starPath, "center", -0.7);
                        if tStar then
                            starImage:removeAllChildren();
                            starImage:addChild(tStar);
                        end
                    end
                else
                    -- 无法派遣
                    -- 虚化显示宠物头像和背景，显示星级和要求的星级
                    iconImage:setOpacity(125.5);
                    bgImg:setVisible(true);

                    -- 设置星阶
                    -- 星级控件
                    starImage:setVisible(true);
                    local maxStarNum = self.rankRequest;
                    if maxStarNum < data.rank then
                        maxStarNum = data.rank;
                    end
                    if data then
                        local starPath = "images/ui/symbol/star_little.png";

                        -- 如果冈布奥已觉醒，使用橙色的星星
                        if AwakeM.isCarved(data.classId) then
                            starPath = "images/ui/symbol/star_little3.png";
                        end
                        local tStar = createStarLayerEx(data.rank, maxStarNum, starPath,
                            "images/ui/symbol/star_little2.png", "center", -0.7);
                        if tStar then
                            starImage:removeAllChildren();
                            starImage:addChild(tStar);
                        end
                    end
                end

                -- 判断是否已经派遣了
                if self:islistor(data.classId) then
                    tipImage:loadTexture(getCornerImg("linked"));
                    tipImage:setVisible(true);
                end

                if TrainingM.isUpgrading(data.classId) then
                    tipImage:loadTexture(getCornerImg("training"));
                    tipImage:setVisible(true);
                elseif AwakeM.isCarving(data.classId) then
                    tipImage:loadTexture(getCornerImg("training"));
                    tipImage:setVisible(true);
                end
            else
                -- 玩家未获得该宠物

                -- 灰化背景，显示宠物头像的剪影，不显示星级
                iconImage:loadTexture(getHeroSilhouetteIconPath(data.classId));
                bgImg:setVisible(true);
            end
        end
    end

    self:refreshExplain();

    -- 设置选择按钮是否可用
    local btnSelect = findChildByName(self.node, "BT/choose_btn");
    btnSelect:setBright(false);
    btnSelect:setTouchEnabled(false);

    local data = self.data[self.selectIndex];
    if not data then
        return;
    end

    if self:canDispatch(data.classId) then
        btnSelect:setBright(true);
        btnSelect:setTouchEnabled(true);
    end
end

-- 设置说明
function UILictorChoose:refreshExplain()
    local data = self.data[self.selectIndex];

    -- 先把标题和描述隐藏起来
    local captionLabel = findChildByName(self.CT, "bg_2/caption_label");
    captionLabel:setVisible(false);
    local Label = findChildByName(self.CT, "bg_2/explain_scroll/explain");
    Label:setVisible(false);

    if not data then
        data = {};
        data.skillLevel = 0;
        return;
    end

    -- 系别名称
    -- SLIMED-1291， 屏蔽掉系别名称
    -- local campLabel = findChildByName(self.CT, "bg_2/camp_label");
    -- campLabel:setVisible(true);
    -- TextStyleM.setTextStyle(campLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BLUE);

    local depId    = PetM.query(data.classId, "department_order")[1];
    -- local careerName = CareerM.getDepartmentName(depId);
    -- applyString(campLabel, careerName);

    -- 将技能名设置为标题
    captionLabel:setVisible(true);
    TextStyleM.setTextStyle(captionLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_DARK_RED);

    local lictorPet = PetM.getMyPet(data.classId);

    if not lictorPet then
        -- 尚未获得冈布奥，仅显示技能名称
        applyString(captionLabel, data.skillName);
    else
        applyString(captionLabel, data.skillName .. " Lv." .. data.skillLevel);
    end

    -- 技能描述
    local explainText = "";
    local explainLabel = findChildByName(self.CT, "bg_2/explain_scroll/explain");
    explainLabel:setVisible(true);
    local fontSize = TextStyleM.TEXT_SIZE_SMALL;
    if getLang() == "th" then
        fontSize = TextStyleM.TEXT_SIZE_SMALL2;
    end
    TextStyleM.setTextStyle(explainLabel, fontSize, TextStyleM.TEXT_COLOR_DARK_BROWN);

    explainText = data.skillDesc;

    -- 如果是不满足条件的，那么还需要加上是被什么条件限制了
    if not lictorPet then
        -- "[gray]尚未获得%s冈布奥！[-]"
        explainText = string.format(getLocStr("lictor_explain3"), data.skillName, data.name);
    elseif not self:canDispatch(data.classId) then
        -- "[gray]%s冈布奥当前无法灵魂链接！[-]"
        explainText = explainText .. "\n\n" .. string.format(getLocStr("lictor_rank_request"), data.name);
    else
        local function isAlreadyActive()
            local lictorList = self.lictorPets;
            local depList = {};
            for _, id in pairs(lictorList) do
                table.insert(depList, PetM.query(id, "department_order")[1]);
            end
            if table.indexOf(depList, depId) ~= -1 then
                return true;
            else
                return false;
            end
        end
        -- "[blue]与%s灵魂链接！\n获得%s效果！[-]"
        explainText = explainText .. "\n\n" .. string.format(getLocStr("lictor_explain"), data.name, data.skillName);

        if isAlreadyActive() == false
            and PetM.query(self.classId, "department_order")[1] ~= depId then
            -- 还未激活，需要额外增加一句
            explainText = explainText .. "\n" .. string.format(getLocStr("lictor_explain2"), CareerM.getDepartmentInfo(depId, "name"));
        end

        -- 进入迷宫时，根据星阶增加初始探索点
        local LictorProps = FormulaM.invoke("GET_LICTOR_SPECIAL_PROPS", data.rank);
        local enterSpStr = PropM.getPropDesc(LictorProps[1]);
        explainText = explainText .. "\n[blue]" .. enterSpStr .. "[-]";
    end

    applyString(explainLabel, explainText);

    -- 徽章阵营图标
    local campIconImage = findChildByName(self.CT, "bg_2/camp_icon");
    campIconImage:loadTexture(getCampIconPath(self.campId));
end

-- 对冈布奥进行排序  按已激活 > 未激活，星级高 > 星级低 排序
function sortLictor(item1, item2)
    if item1.noPet ~= item2.noPet then
        return item1.noPet < item2.noPet;
   else
      return item1.rank > item2.rank;
    end
end

-- 初始化扈从数据
function UILictorChoose:initData()
    self.data = {};

    for _, classId in pairs(self.campPets) do
        local pet = PetM.getMyPet(classId);
        local item = {};

        -- 系别
        local departOrder = PetM.query(classId, "department_order");
        item.depart = departOrder[1];

        -- 获取数据
        if pet then
            -- 有宠物的话，取宠物的数据
            item.classId = classId;
            item.name = PetM.query(classId, "name");
            item.rank = pet.rank;

            -- 计算宠物专属技能的真实技能id
            local skillId = pet["special"];

            skillId = FormulaM.invoke("CALC_FINAL_SKILL", pet, skillId);
            item.skillId = skillId;
            item.noPet = 0;
        else
            -- 未获得宠物的话，去配置表的数据
            item.classId = classId;
            item.name = PetM.query(classId, "name");
            item.rank = PetM.query(classId, "init_rank");
            item.skillId = PetM.query(classId, "special");
            item.noPet = 1;
        end

        -- 获取技能等级、名称、描述。这里技能描述使用 "lictor" 规则的技能描述
        item.skillLevel = SkillM.query(item.skillId, "level");
        item.skillName = SkillM.query(item.skillId, "name");
        item.skillDesc = SkillM.getSkillDesc(item.skillId, false, "lictor");

        -- 当前出战冈布奥不显示
        if self.classId ~= classId then
            table.insert(self.data, item);
        end
    end

    -- 对宠物进行排序
    table.sort(self.data, sortLictor);
end

-- 初始化扈从格
function UILictorChoose:initLictorGrids(node)
    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 图标间距(横向)
    local wGap = 10;

    -- 图标间距(纵向)
    local hGap = 8;

    -- 图标宽度
    local iconWidth = 110;

    -- 图片高度
    local iconHeight = 115;

    local topHGap  = 10;
    local leftWGap = 13;

    local bottomHGap = 20;
    -- 收集扈从信息
    local lictorsList = self.data;

    -- 扈从的总个数
    local lictorCount = #lictorsList;

    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/lictor/LictorItem.csb");
    -- 扈从格背景
    local bgImg = itemNode:getChildByName("bg");
    local bgImgGray = itemNode:getChildByName("gray_bg");
    local focusImg = itemNode:getChildByName("focus");

    bgImg:loadTexture(getHeroImgBg("hero_info"));
    bgImgGray:loadTexture(getHeroImgBg("hero_info_idle"));
    focusImg:loadTexture(getHeroImgBg("hero_info_focus"));

    itemNode:setScale(0.88);

    -- @param windowNode    界面节点
    -- @param scrollNode    容器节点
    -- @param itemNode      单元格的节点
    -- @param totalNum      单元格总数
    -- @param maxRowNum     最大行数
    -- @param pageColNum    单页可以显示下的列数
    -- @param wGap          单元格间距(横向) 这里作为最小值使用
    -- @param hGap          单元格间距(纵向)
    -- @param iconWidth     单元格宽度
    -- @param iconHeight    单元格高度
    -- @param topHGap       上方留
    -- @param leftWGap      左右留白  这里作为最小值使用
    -- @param touchEvent    点击事件注册函数
    initScrollGridsVertical(self, self.scrollView, itemNode, lictorCount, MAX_GRID_ROW, MIN_GRID_COLUMN, wGap, hGap, iconWidth, iconHeight, topHGap, bottomHGap, leftWGap, self.registerLictorItemTouchEvent);
end

-- 清空所有的扈从格
function UILictorChoose:clearAllGrid()
    -- 格子总数
    local totalGridCount = #self.data;
    for i = 1, totalGridCount do
        local grid = self.scrollView:getChildByName(ITEM_NAME .. i);
        if grid then
            grid:setVisible(false);
        end
    end
end

-- 注册扈从点击事件
function UILictorChoose:registerLictorItemTouchEvent(node)
    local image = node:getChildByName("bg");
    local grayImage = node:getChildByName("gray_bg");
    local function onClick(sender, eventType)
        -- 点击时的回调
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            if self.data[node.index] == nil then
                return;
            end
            local lastSelected = self.selectIndex;

            self.selectIndex = node.index;

            self:lictorSelected(lastSelected, node.index);
            -- self:redraw();
        end
    end

    image:addTouchEventListener(onClick);
    grayImage:addTouchEventListener(onClick);
end

-- 注册点击事件
function UILictorChoose:registerTouchEvent()
    local node = self.node;

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UILictorChoose");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册选择按钮点击事件
    local btnSelect = findChildByName(node, "BT/choose_btn");
    local function onSelectClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            local data = self.data[self.selectIndex];
            if self:canDispatch(data.classId) then
                EventMgr.fire(event.LICTOR_CHOOSE_OK, {["classId"] = data.classId, ["itemId"] = self.itemId});

                -- 关闭当前界面
                UIMgr.getCurrentScene():removeFormByName("UILictorChoose");
            end
        end
    end

    btnSelect:addTouchEventListener(onSelectClick);
    TextStyleM.setTextStyle(btnSelect, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnSelect:setTitleText(getLocStr("btn_text_select"));
end

-- 适配
function UILictorChoose:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");

    -- TOP顶部居中并缩放至合适大小
    --AlignM.alignToTopCenter(node, "TOP");
end

-- 扈从选中效果
function UILictorChoose:lictorSelected(lastSelected, nowSelected)
   -- 清除上次选中效果
    local lastSel = self.scrollView:getChildByName(ITEM_NAME .. lastSelected);
    local focusBg = lastSel:getChildByName("focus");
    focusBg:setVisible(false);

    -- 新选中的效果
    local nowSel = self.scrollView:getChildByName(ITEM_NAME .. nowSelected);
    local nowFocusBg = nowSel:getChildByName("focus");
    nowFocusBg:setVisible(true);

    -- 更新说明和按钮
    self:refreshExplain();

    -- 更新选择按钮
    local data = self.data[self.selectIndex];
    local btnSelect = findChildByName(self.node, "BT/choose_btn");

    if not data then
        btnSelect:setBright(false);
        btnSelect:setTouchEnabled(false);
        return;
    end

    if self:canDispatch(data.classId) then
        btnSelect:setBright(true);
        btnSelect:setTouchEnabled(true);
    else
        btnSelect:setBright(false);
        btnSelect:setTouchEnabled(false);
    end
end

-- 判断是否已经派遣了
function UILictorChoose:islistor(classId)
    local lictorPets = self.lictorPets;

    if not lictorPets then
        return false;
    end

    for item, id in pairs(lictorPets) do
        if id == classId then
            if item == "item"..self.itemId then
                return false;
            else
                return true;
            end
        end
    end

    return false;
end

-- 判断能否派遣
function UILictorChoose:canDispatch(classId)
    local activePet = ME.user.dbase:query("active_pet");

    -- 不能是出战的宠物
    if (classId == activePet) then
        return false;
    end

    -- 必须是已激活的宠物
    if (PetM.isActivated(classId) == false) then
        return false;
    end

    -- 必须跟出战宠物同阵营
    if (not IsInTable(classId, CampM.getCampPets(activePet))) then
        return false;
    end

    -- 正在训练中
    if TrainingM.isUpgrading(classId) or
        AwakeM.isCarving(classId) then
        return false;
    end

    -- 判断阶位是否符合条件
    local pet = PetM.getMyPet(classId);

--    if pet:getRank() < self.rankRequest then
--        return false;
--    end

    return true;
end